use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, AttributeArgs, ItemFn};

#[proc_macro_attribute]
pub fn name_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
    let name = parse_macro_input!(attr as AttributeArgs).pop().unwrap();
    let name_value = match name {
        syn::NestedMeta::Lit(syn::Lit::Str(name)) => name.value(),
        _ => return quote! { compile_error!("Expected a string literal") }.into(),
    };

    let input = parse_macro_input!(item as ItemFn);
    let fn_name = &input.sig.ident;

    let gen = quote! {
        #input

        #[doc(hidden)]
        #[allow(non_upper_case_globals)]
        pub mod #fn_name {
            pub const name: &str = #name_value;
        }
    };

    gen.into()
}

// #[cfg(test)]
// mod tests {
//     use super::*;

//     #[test]
//     fn test_name_macro() {
//         let input = quote! {
//             #[name_macro(name = "my_function")]
//             fn my_function() {}
//         };

//         let output = name_macro(input.into(), TokenStream::new());

//         assert_eq!(
//             output.to_string(),
//             quote! {
//                 #[allow(unused_attributes)]
//                 #[attribute(name = "my_function")]
//             }
//         )
//     }
// }
